

/*
 * @Author       : Liang
 * @Date         : 2024-11-10
 * @Version      : 1.0-------
 * @Description  : iotv30_main.c
 */
 //1.0-------2024-11-10
 //1.2-------2025-3-18
/*

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <memory.h> /*使用memcpy所需的头文件*/

#include <time.h>
#include <unistd.h>   //sleep
#include <errno.h>
#include <fcntl.h>

#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>

#include <sys/time.h>
#include <pthread.h>

#include <signal.h>

#include "app_types.h"

#include "gui_logist.h"
#include "iotv30_config.h"
#include "f133_drv_config.h"
#include  "gw_ktj_api_config.h"

#include "led.h"
#include "meter.h"
#include "plcgw_sys.h"
#include "read_local_file.h"
#include "uart_printf.h"
#include "user_flash.h"

//#include "CRC_Check.h"
#include "timer_app.h"

#include  "TimeBase.h"
#include "rtc_calendar.h"


//#include <unistd.h>
#include <sys/reboot.h>

#include  "system.h"


#include "tcp_api_01.h" 
#include "gw_ktj_tcp_client.h" 
#include "iotv30_tcp_client.h" 

#include "iotv30_app.h"

#include "iotv30_main.h"



 platform_info_t platform_info; 

 
#if IOTV30_thread_enable
int iotv30_main(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif    
{

	//ClientInfo_st  ClientInfo;   //debug
    //printf(cct_ver_str);
 

    sleep(5);  //等待南向先启动

    logout("app_name: %s\r\n", argv[0]);//app_name 
    LOG_NAME();

//------ver.4.24-----20240306---------------------------------
 //  logout("SoftWare_Ver.%02d.%02d.%02d.%02d\r\n",CCT_SW_VerHex[0],CCT_SW_VerHex[1],CCT_SW_VerHex[2],CCT_SW_VerHex[3] ); //软件版本号FW_Version
 //  logout("HardWare_Ver.%02d.%02d.%02d.%02d\r\n",CCT_HW_VerHex[0],CCT_HW_VerHex[1],CCT_HW_VerHex[2],CCT_HW_VerHex[3] ); //硬件版本号 HW_Version

    logout("SoftWare_Ver.%04x\n", app_get_ver() ) ;

    UserFlash_Create( );
    printf(" UserFlash_Create() done\n\r" );

    settime_alarm();
    printf(" settime_alarm() done\n\r" );


    Tcp_API_Init( );


    iotv30_Tcp_Client_Init( );
    printf(" iotv30_Tcp_Client_Init() done\n\r" );		

    gw_ktj_Tcp_Client_Init( );
    printf(" gw_ktj_Tcp_Client_Init() done\n\r");	


    LED_init( );

    UserFlash_Init( ); 
    printf(" UserFlash_Init() done\n\r" );	

    read_local_data_cfg_dat(  );
    gui_logist_init( );
    Meter_Init( );


 	//strcpy(platform_info.gw_id, gw_id);



//新的路灯协议---IoTv3.0---protobuf协议  

   iotv30_app_init( );

	//plcgw_sysmsg_init( );



    Timer_App_Init( );   
    printf(" Timer_App_Init() done\n\r" );
    logout("v%04x-sw%s-hw%s\n", app_get_ver(),get_gateway_swVer(), get_gateway_hwVer());


#if 1

    if( 1==argc )
    { //# 139.9.31.177 10086 -----没有命令参数输入----使用已经配置 的参数

	// printf("north1_ip=%s\n", gw_commu_info.platform_cfg[1].ip);
	// printf("north1_port=%d\n", gw_commu_info.platform_cfg[1].port);
	// printf("north1_protocol=%d\n", gw_commu_info.platform_cfg[1].protocol);
	// printf("north1_heartbeastTime=%d\n", gw_commu_info.platform_cfg[1].heartbeast_time);
	

#if 0   //服务器ip 来自调试地址
         ClientInfo[TCP_API_CH_IOTV30].addr.sin_addr.s_addr = inet_addr(defualt_ip_str_ktj );    //服务端地址
         ClientInfo[TCP_API_CH_IOTV30].addr.sin_port        = htons(atoi(defualt_port_str_ktj));

        printf("north default server ip: %s, port: %s\n\r", defualt_ip_str_ktj, defualt_port_str_ktj);
#endif   

//--------------获取服务器--ip------

#if 1  //服务器ip 来自内部flash
        ClientInfo[TCP_API_CH_IOTV30].addr.sin_addr.s_addr = inet_addr( rlf_read_gw_ip(GW_INI_CH_north1 ) );    //服务端地址
        ClientInfo[TCP_API_CH_IOTV30].addr.sin_port        = htons(rlf_read_gw_port( GW_INI_CH_north1 )  );

        printf("iotv30 server ip: %s, port: %d\n\r", rlf_read_gw_ip(GW_INI_CH_north1 ), rlf_read_gw_port( GW_INI_CH_north1 ) );
#endif        


    }else if (2== argc)
    {
        printf("too few arguments to app, argc: %d\n\r", argc);
        return 0;

    }else{ //从命令行输入 服务器 ip及port

        printf("north config server ip: %s, port: %s\n\r", argv[1], argv[2]);

        ClientInfo[TCP_API_CH_IOTV30].addr.sin_addr.s_addr = inet_addr(argv[1]);    //服务端地址
        ClientInfo[TCP_API_CH_IOTV30].addr.sin_port        = htons(atoi(argv[2]));
    }

#endif


 
#if 1   //服务器ip 来自调试地址
         ClientInfo[TCP_API_CH_LOCAL].addr.sin_addr.s_addr = inet_addr(gw_ktj_local_json_server_ip_str );    //本地服务端地址
         ClientInfo[TCP_API_CH_LOCAL].addr.sin_port        = htons(atoi(gw_ktj_local_json_server_port_str));

        printf("gw_ktj_local server ip: %s, port: %s\n\r", gw_ktj_local_json_server_ip_str, gw_ktj_local_json_server_port_str);
#endif   



    printf("north server ip: 0x%x, port: %d\n\r",  ClientInfo[TCP_API_CH_IOTV30].addr.sin_addr.s_addr, ClientInfo[TCP_API_CH_IOTV30].addr.sin_port);
    printf("gw_ktj_local server ip: 0x%x, port: %d\n\r",  ClientInfo[TCP_API_CH_LOCAL].addr.sin_addr.s_addr, ClientInfo[TCP_API_CH_LOCAL].addr.sin_port);


	printf("我是主线程， ID: %ld\n\r", pthread_self() ); // l


    Timer_App_Config_1ms( );  ///定时器放在最后
    printf(" Timer_App_Config_1ms() done\n\r" );


    printf("iotv30 init done\n" );


    while (1)
    {

        if(  0 != iotv30_Tcp_Client_App_Process( &ClientInfo[TCP_API_CH_IOTV30] )  )
        { 
			//由于同一个进程内的所有线程共享内存和变量，因此在传递参数时需作特殊处理，值传递。
			pthread_create(&(ClientInfo[TCP_API_CH_IOTV30].tid) , NULL, (void *)iotv30_Tcp_Client_RecvProcess, (void *)&(ClientInfo[TCP_API_CH_IOTV30].fd) );  //创建线程
			pthread_detach(ClientInfo[TCP_API_CH_IOTV30].tid); // 线程分离，结束时自动回收资源
		
			printf("子线程创建成功,iotv30_Tcp_Client_RecvProcess tid: %ld\n\r", ClientInfo[TCP_API_CH_IOTV30].tid);//%ld\n

#if  (DEBUG_PRINT_ENABLE || DEBUG_MIN_PRINT_ENABLE )
			system("netstat -ant | grep 10096");	// 查看连接状态 
			//system("netstat -an ");	// 查看连接状态 		
#endif
		}
	


        if(  0 != gw_ktj_Tcp_Client_App_Process( &ClientInfo[TCP_API_CH_LOCAL] )  )
        { 
			//由于同一个进程内的所有线程共享内存和变量，因此在传递参数时需作特殊处理，值传递。
			pthread_create(&(ClientInfo[TCP_API_CH_LOCAL].tid) , NULL, (void *)gw_ktj_Tcp_Client_RecvProcess, (void *)&(ClientInfo[TCP_API_CH_LOCAL].fd) );  //创建线程
			pthread_detach(ClientInfo[TCP_API_CH_LOCAL].tid); // 线程分离，结束时自动回收资源
		
			printf("子线程创建成功,gw_ktj_Tcp_Client_RecvProcess tid: %ld\n\r", ClientInfo[TCP_API_CH_LOCAL].tid );  //%ld\n

#if  (DEBUG_PRINT_ENABLE || DEBUG_MIN_PRINT_ENABLE )
			system("netstat -ant | grep 13336");	// 查看连接状态 
			//system("netstat -an ");	// 查看连接状态 		
#endif

		}
	
        UserFlash_SaveProcess( );

//--------新的路灯协议---IoTv3.0---protobuf协议 ----------------------------------------------------------------
        iotv30_app_process( );
		//system("netstat -an | grep 10086"); // 查看连接状态  
	   usleep(10000);

    }


   //----???????
	// close(ClientInfo[TCP_API_CH_LOCAL].fd);
	// ClientInfo[TCP_API_CH_LOCAL].fd = -1;
			
	// close(ClientInfo[TCP_API_CH_IOTV30].fd);
	// ClientInfo[TCP_API_CH_IOTV30].fd = -1;


  return 0;  

}





#if IOTV30_thread_enable


static void *iotv30_thread(void *p)
{
	pthread_detach(pthread_self());   
	////
	char port_buf[8];

    LOG_NAME();

	sprintf(port_buf, "%d", platform_info.port);
	
	char *argv[3];
	argv[0] = "iotv30_main";
	argv[1] = platform_info.ip;
	argv[2] = port_buf;


	printf("iotv30 : ip=%s, port=%s\n", argv[1], argv[2]);
	
#if IOTV30_thread_enable
	iotv30_main(3,  argv);    //  no return !
#endif   


	pthread_exit(NULL);
	return NULL;

}


  pthread_t tid_iotv30;//debug----测试ok

//int iotv30_init(const char *ip, int port)
 int iotv30_init(const char *ip, int port, const char *gw_id)
{
  //  static	pthread_t tid_iotv30;  //debug-----尚未测试验证------
    LOG_NAME();

	strcpy(platform_info.ip, ip);
 	strcpy(platform_info.gw_id, gw_id);
   
	platform_info.port = port;
    printf("gw_id=%s,ip=%s,port=%d,\n",platform_info.gw_id,platform_info.ip,platform_info.port);

	//return 0;

	//pthread_t tid_iotv30;  //bug
	return pthread_create(&tid_iotv30, NULL, iotv30_thread, NULL);
    
	
}



////


int iotv30_init888(const char *ip, int port)
{
static	pthread_t tid_iotv30;  //debug-----

	strcpy(platform_info.ip, ip);
	platform_info.port = port;
    LOG_NAME();
	//return 0;


	 pthread_create(&tid_iotv30, NULL, iotv30_thread, NULL);	
	 pthread_detach( tid_iotv30	); // 线程分离，结束时自动回收资源  

	 printf("thread creat ok,iotv30_thread tid: %ld\n\r", tid_iotv30 ) ;

return 1;

}


#endif   






















